
#include "StateManager.h"

#include "StateIntro.h"
#include "StateMainMenu.h"
#include "StateOptions.h"
#include "StateStats.h"
#include "StateMuseum.h"
//#include "StateShop.h"
#include "StateShopAnimals.h"
#include "StateShopAnimalDetail.h"
//#include "StateShopUpgrades.h"
//#include "StateShopPowerUps.h"
#include "StateCoinsPopUp.h"
#include "StatePopUp.h"
#include "StateGame.h"
#include "StatePause.h"
#include "StateEndGame.h"

#include "InputManager.h"
#include "SpriteEffectManager.h"
#include "defs.h"
#include "TextureManager.h"
#include "TextManager.h"
#include "ProgressManager.h"

StateManager::StateManager()
{
    m_eCurrentOperation = None;
}

StateManager::~StateManager()
{
	
}

void StateManager::manageStateChange()
{
    eStateOperation eCurrentOperation = m_eCurrentOperation;
    GameState* gsNewState = m_gsNewState;
    
    m_eCurrentOperation = None;
    m_gsNewState = NULL;

    switch(eCurrentOperation)
    {
        case PushState:
            m_vStates.push_back(gsNewState);
            gsNewState->enter();
            break;
            
        case PopState:
            m_vStates.back()->exit();
            m_vStates.pop_back();
            m_vStates.back()->activated();
            break;
            
        case PopStateUntil:
            while(m_vStates.size() > 0 && m_vStates.back() != gsNewState)
            {
                m_vStates.back()->exit();
                m_vStates.pop_back();
            }
            break;
            
        case SetState:
            while(m_vStates.size() > 0)
            {
                m_vStates.back()->exit();
                m_vStates.pop_back();
            }
            
            m_vStates.clear();
            m_vStates.push_back(gsNewState);
            gsNewState->enter();
            break;
        default:
            break;
    }
}

void StateManager::setState(GameState& _newState)
{
    m_gsNewState = &_newState;
    m_eCurrentOperation = SetState;
}

void StateManager::popState()
{
    m_eCurrentOperation = PopState;
}

void StateManager::popStateUntil(GameState& _newState)
{
    m_gsNewState = &_newState;
    m_eCurrentOperation = PopStateUntil;
}

void StateManager::pushState(GameState& _newState)
{
    m_gsNewState = &_newState;
    m_eCurrentOperation = PushState;
}

void StateManager::init()
{
	setupFade();

    ProgressManager::instance().load();

    //preload states
	StateIntro::instance().loadContent();
	StateMainMenu::instance().loadContent();
	StatePopUp::instance().loadContent();
	StateOptions::instance().loadContent();
	StateStats::instance().loadContent();
    StateCoinsPopUp::instance().loadContent();
	StateMuseum::instance().loadContent();
	StateGame::instance().loadContent();
	StateEndGame::instance().loadContent();
	StatePause::instance().loadContent();

//    StateShop::instance().loadContent();
	StateShopAnimals::instance().loadContent();
	StateShopAnimalDetail::instance().loadContent();
//	StateShopUpgrades::instance().loadContent();
//	StateShopPowerUps::instance().loadContent();

    setState(StateMainMenu::instance());
    manageStateChange();
}

void StateManager::update(float dt)
{
    SB::dt = dt;
    SB::gameTime += SB::dt;
    
    if(m_eCurrentOperation != None)
        manageStateChange();

    SpriteEffectManager::instance().update(dt);

    for(int i=0; i<m_vStates.size()-1; ++i)
    {
        m_vStates.at(i)->updatePaused(dt);
    }

    m_vStates.back()->updatePaused(dt);
    m_vStates.back()->update(dt);

    InputManager::instance().updateInputs();
}

void StateManager::render()
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    for(int i=0; i<m_vStates.size(); ++i)
    {
        TextManager::instance().clearTexts();
        m_vStates.at(i)->render();
        TextManager::instance().render();
    }
	
    m_reFade->render();
}

void StateManager::pause(bool _bValue)
{
    if(m_vStates.back()->canPause())
    {
        pushState(StatePause::instance());
    }
}


//FADE

void StateManager::setupFade()
{
    m_reFade = new RenderableEntity("fade", Vector2(0, 0));
    m_reFade->setScale(Vector2(640, 960));
    m_reFade->setColor(Vector4(0,0,0,1));
    m_reFade->setAlpha(0);
    
    m_feFade = new FadeEffect(m_reFade, FADE_TIME, false, false, 0, 1);
}

void StateManager::fadeIn(float _fTime)
{
    m_feFade->setDuration(_fTime);
    m_feFade->setParams(1, 0);
    m_feFade->reset();
    m_feFade->setEnabled(true);
}

void StateManager::fadeOut(float _fTime)
{
    m_feFade->setDuration(_fTime);
    m_feFade->setParams(0, 1);
    m_feFade->reset();
    m_feFade->setEnabled(true);
}

bool StateManager::isFading()
{
    return !m_feFade->isFinished();
}
